DepositData.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. "use client";
  2. import { DepositsTypes, RewardsType } from "@/api/depositsApi";
  3. import { getUserRechargeApi } from "@/api/user";
  4. import Box from "@/components/Box";
  5. import { useUserInfoStore } from "@/stores/useUserInfoStore";
  6. import { neReg } from "@/utils";
  7. import { Form, Input, Toast } from "antd-mobile";
  8. import { FormInstance } from "antd-mobile/es/components/form";
  9. import { useTranslations } from "next-intl";
  10. import { FC, Fragment, useLayoutEffect, useRef, useState } from "react";
  11. import ButtonOwn from "@/components/ButtonOwn";
  12. import "@/styles/deposit.scss";
  13. import { server } from "@/utils/client";
  14. import Image from "next/image";
  15. interface Props {
  16. deposits: DepositsTypes[];
  17. }
  18. interface RewardsProps {
  19. rewards: RewardsType[];
  20. }
  21. const RewardsText: FC<RewardsProps> = (props) => {
  22. const { rewards } = props;
  23. // {/*1现金2彩金3免费币4重玩币*/}
  24. const t = useTranslations();
  25. const calcRewards = rewards
  26. .map((item) => {
  27. // 根据coin_type添加后缀
  28. const suffixes = {
  29. 1: t("ProfilePage.balance"),
  30. 2: t("ProfilePage.balance"),
  31. 3: t("ProfilePage.free"),
  32. 4: t("ProfilePage.replay"),
  33. };
  34. let text = "";
  35. // 设置基础奖励文本
  36. if (item.ratio > 0) {
  37. text = `${item.ratio}`;
  38. } else {
  39. text = `${item.reward}`;
  40. }
  41. if (item.ratio > 0 && item.reward > 0) {
  42. text = `${item.ratio}%${suffixes[item.coin_type]}, ${item.reward}`;
  43. }
  44. // 如果coin_type在suffixes中存在,则添加相应的后缀
  45. if (suffixes.hasOwnProperty(item.coin_type)) {
  46. text += suffixes[item.coin_type];
  47. }
  48. return text;
  49. })
  50. .join(",");
  51. return (
  52. <div className={"flex flex-1 flex-wrap break-all"}>
  53. <span className="amountTips">+ {calcRewards} </span>
  54. </div>
  55. );
  56. };
  57. const getDepositApi = async () => {
  58. return server
  59. .request<DepositsTypes[]>({
  60. url: "/v1/api/user/user_deposit_config",
  61. method: "post",
  62. data: { activity_type: 2 },
  63. })
  64. .then((res) => {
  65. if (res.code === 200) return res.data;
  66. return [];
  67. });
  68. };
  69. const DepositData: FC<Props> = (props) => {
  70. // const { deposits } = props;
  71. const t = useTranslations();
  72. const userInfo = useUserInfoStore((state) => state.userInfo);
  73. // 选中类型
  74. const [depositState, setDepositState] = useState<DepositsTypes[]>([]);
  75. const [activeType, setActiveType] = useState<Partial<DepositsTypes>>({});
  76. const count = activeType.num || 0;
  77. const formInstanceRef = useRef<FormInstance>(null);
  78. let [amount, setAmount] = useState<number | undefined>(undefined);
  79. const titleChangeHandler = (item: DepositsTypes, index: number) => {
  80. setAmount(undefined);
  81. setActiveType(item);
  82. formInstanceRef.current?.resetFields();
  83. };
  84. const isStrictMode = true;
  85. const onFinish = (values: any) => {
  86. const params = { ...values, channel_id: activeType.id, amount: +values.amount };
  87. getUserRechargeApi(params)
  88. .then(async (res) => {
  89. formInstanceRef.current?.resetFields();
  90. Toast.show({ icon: "success", content: t("code.200"), maskClickable: false });
  91. setAmount(undefined);
  92. const data = await getDepositApi();
  93. setDepositState(data);
  94. setActiveType(data[0]);
  95. if (res.data.pay_url) {
  96. window.open(res.data.pay_url);
  97. }
  98. })
  99. .catch((error) => {
  100. Toast.show({ content: t(`code${error.data.code}`), maskClickable: false });
  101. });
  102. };
  103. const onValuesChange = (changeValues: any) => {
  104. if (changeValues.amount) {
  105. setAmount(changeValues.amount);
  106. }
  107. };
  108. const amountChange = (value: number) => {
  109. formInstanceRef.current?.setFieldValue("amount", value);
  110. setAmount(value);
  111. };
  112. const amountValidator = (rules: any, value: any) => {
  113. if (!value) return Promise.reject(new Error(t("form.amount")));
  114. if (+value < activeType.min_amount!)
  115. return Promise.reject(
  116. new Error(t("form.amountMinReg", { amount: activeType.min_amount }))
  117. );
  118. if (+value > activeType.max_amount!)
  119. return Promise.reject(
  120. new Error(t("form.amountMaxReg", { amount: activeType.max_amount }))
  121. );
  122. return Promise.resolve();
  123. };
  124. useLayoutEffect(() => {
  125. getDepositApi().then((data) => {
  126. setDepositState(data);
  127. setActiveType(data[0]);
  128. });
  129. }, []);
  130. return (
  131. <>
  132. <Image src={"/doings/recharge.jpg"} alt={"deposit"} width={1950} height={10} />
  133. <div className="deposit-box">
  134. <div className={"flex items-center"}>
  135. <div className="img-box"></div>
  136. <div className={"flex-1 text-right"}>
  137. <i
  138. className={"iconfont icon-star_full text-[0.15rem] text-primary-color"}
  139. ></i>
  140. {`{${count}} recargas restantes`}
  141. </div>
  142. </div>
  143. <div className={"flex flex-wrap"}>
  144. {depositState.map((item, index) => {
  145. return (
  146. <Fragment key={item.id}>
  147. <p
  148. className="btn-box truncate"
  149. style={{
  150. borderColor: activeType.id === item.id ? "#ff9323" : "#333",
  151. }}
  152. onClick={() => titleChangeHandler(item, index)}
  153. >
  154. {item.name}
  155. </p>
  156. </Fragment>
  157. );
  158. })}
  159. </div>
  160. <Box className={"custom-form"} style={{ padding: 0 }}>
  161. <Form
  162. style={{
  163. "--border-bottom": "none",
  164. "--border-top": "none",
  165. "--border-inner": "none",
  166. }}
  167. ref={formInstanceRef}
  168. initialValues={userInfo}
  169. onFinish={onFinish}
  170. onValuesChange={onValuesChange}
  171. footer={
  172. <>
  173. <ButtonOwn active>{t("DepositPage.DepositarAgora")}</ButtonOwn>
  174. </>
  175. }
  176. >
  177. {isStrictMode ? (
  178. <>
  179. <Form.Item
  180. name="user_name"
  181. label=""
  182. rules={[{ required: true, message: t("form.usernameReg") }]}
  183. >
  184. <Input placeholder={t("form.username")} />
  185. </Form.Item>
  186. <Form.Item
  187. name="passport"
  188. label=""
  189. rules={[
  190. {
  191. required: true,
  192. message: t("form.cardReg"),
  193. pattern: neReg,
  194. },
  195. ]}
  196. >
  197. <Input
  198. placeholder={t("form.card")}
  199. maxLength={11}
  200. type={"text"}
  201. />
  202. </Form.Item>
  203. </>
  204. ) : null}
  205. <Form.Item
  206. name="amount"
  207. label=""
  208. rules={[{ required: true, type: "number", validator: amountValidator }]}
  209. >
  210. <Input
  211. placeholder={`${t("DepositPage.Montante")}(BRL): Mín. ${activeType.min_amount}`}
  212. type={"number"}
  213. maxLength={activeType.max_amount}
  214. />
  215. </Form.Item>
  216. <div className={"flex flex-col"}>
  217. <div className={"flex-1"}>
  218. <ul className="ul-box">
  219. {activeType?.products?.map((item, index) => (
  220. <li
  221. className={amount == item.amount ? "active" : ""}
  222. key={index}
  223. onClick={() => amountChange(item.amount)}
  224. >
  225. {!!item.badge && <span className="hot"></span>}
  226. <div className="amountContent">
  227. {/* <span className="iconfont icon-unit-brl"></span> */}
  228. <span className="iconfont">R$</span>
  229. <span> {item.amount}</span>
  230. </div>
  231. <div className={"flex"}>
  232. {item.rewards && (
  233. <RewardsText rewards={item.rewards} />
  234. )}
  235. </div>
  236. {/*<span className="amountTips">*/}
  237. {/* {t("DepositPage.Oferecer")} 100%*/}
  238. {/*</span>*/}
  239. </li>
  240. ))}
  241. </ul>
  242. </div>
  243. </div>
  244. </Form>
  245. </Box>
  246. <p className={"text-[#e59c5f]"}>Descrição daatividade:</p>
  247. <p className={"text-[0.12rem] text-[#e59c5f]"}>
  248. Recarregue nas primeiras {`{${count}}`} vezes todos os dias e ganhe desco
  249. </p>
  250. </div>
  251. </>
  252. );
  253. };
  254. export default DepositData;